package com.dataManager.www.utils;

import org.apache.log4j.Logger;

import java.io.*;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class FileUtils {

    private static Logger log = Logger.getLogger("zipfiles");
    /**
     * 移动文件夹内的所有文件到制定文件夹
     * @param from
     * @param to
     * @return
     */
    public static int fileMove(String from, String to) {
        try {
            File dir = new File(from);
            File[] files = dir.listFiles();
            if (files == null) {
                return -1;
            }
            File moveDir = new File(to);
            if (!moveDir.exists()) {
                moveDir.mkdirs();
                System.out.println("已新建一个目标移动文件夹");
            }
            for (File file : files) {
                System.out.println("files[i].isDirectory()：" + file.isDirectory());
                if (file.isDirectory()) {
                    fileMove(file.getPath(), to + dir.separator + file.getName());
                    file.delete();
                }
                File moveFile = new File(moveDir.getPath() + dir.separator + file.getName());
                if (moveFile.exists()) {
                    moveFile.delete();
                }
                file.renameTo(moveFile);
            }
            System.out.println("文件移动成功！");
        } catch (Exception e) {
            System.out.println("移动文件出现异常，异常信息为[" + e.getMessage() + "]");
            return -1;
        }
        return 0;
    }


    //创建方法获取指定文件夹下的文件大小并将其打印出来,参数为文件夹绝对路径,返回值文件的大小
    public static long getFileSize(String file) {
        //创建文件对象
        File f = new File(file);
        if (f.exists() && f.isDirectory()) {//文件夹存在
            //获取文件夹的文件的集合
            File[] files = f.listFiles();
            long count =0;//用来保存文件的长度
            for (File file1 : files) {//遍历文件集合
                if (file1.isFile()) {//如果是文件
                    count += file1.length();//计算文件的长度
                } else {
                    count += getFileSize(file1.toString());//递归调用
                }

            }
            return count;
        }else {
            System.out.println("您查询的文件夹有误");
            return 0;
        }
    }


    //将指定文件夹下的所有文件(除压缩文件除外)压缩，该文件夹下没有子文件夹，否则需递归进行处理
    public static String zipFiles(String sourceFilePath,String filename){
        //判断是否有指定文件夹
        File sourceFile = new File(sourceFilePath);
        if(!sourceFile.exists())
        {
            log.info("待压缩的文件目录："+sourceFile+"不存在");
            return null;
        }

        String zipName =  filename;
        File zipFile = new File(sourceFilePath.substring(0,sourceFilePath.lastIndexOf("/"))+"\\"+zipName+".zip");
        File[] sourceFiles = sourceFile.listFiles();
        if(null == sourceFiles || sourceFiles.length<1){
            log.info("待压缩的文件目录：" + sourceFilePath + "里面不存在文件，无需压缩.");
            return null;
        }

        BufferedInputStream bis = null;
        ZipOutputStream zos = null;
        byte[] bufs = new byte[1024*10];
        FileInputStream fis = null;
        try {
            zos = new ZipOutputStream(new FileOutputStream(zipFile));
            for(int i=0; i<sourceFiles.length; i++){
                //创建zip实体，并添加进压缩包
                String tmpFileName = sourceFiles[i].getName();
                if(tmpFileName.endsWith(".zip"))
                    continue;
                ZipEntry zipEntry = new ZipEntry(tmpFileName);
                zos.putNextEntry(zipEntry);
                //读取待压缩的文件并写进压缩包里
                fis = new FileInputStream(sourceFiles[i]);
                bis = new BufferedInputStream(fis, 1024*10);
                int read = 0;
                while((read=bis.read(bufs, 0, 1024*10))!=-1){
                    zos.write(bufs, 0, read);
                }
                fis.close();//很重要，否则删除不掉!
            }
            log.info("文件打包成功！");

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally{
            //关闭流
            try {
                if(null!=bis)
                    bis.close();
                if(null!=zos)
                    //zos.closeEntry();
                    zos.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        return sourceFilePath.substring(0,sourceFilePath.lastIndexOf("/"))+"\\"+zipName+".zip";
    }


    //删除指定文件夹下的压缩文件
    public static void deleteZipFiles(String filePath) throws ParseException {
        File delFile = new File(filePath);
        if(!delFile.exists())
        {
            //tmpFile.mkdirs();
            log.info("待删除的文件目录："+delFile+"不存在");
            return;

        }

        File[] delFiles = delFile.listFiles();
        if(null == delFiles || delFiles.length<1){
            log.info(filePath+"下没有要删除的文件.");
            return;
        }


        //收集压缩文件，过滤掉非压缩的文件以及文件夹
        List<File> delFilesTarget = new ArrayList<File>();
        for(int i=0; i<delFiles.length; i++){
            String tmpFileName = delFiles[i].getName();
            if(tmpFileName.endsWith(".zip"))//是压缩文件
                delFilesTarget.add(delFiles[i]);
        }

        //计算文件大小总量，然后检查总量是否超过阈值（100KB）。
        //如果超过，则不断删除最老的文件，直至文件总量不再超过阈值
        long len = 0;
        for(int i=0; i<delFilesTarget.size(); i++){
            len += delFilesTarget.get(i).length();//返回字节数
        }
        int threshold = 100000;//100KB，阈值
        int lastIndex = delFilesTarget.size()-1;
        while(len>threshold){
            File delF = delFilesTarget.remove(lastIndex);
            len -= delF.length();
            lastIndex -= 1;

            if(!delF.delete()){
                log.info("文件"+delF.getName()+"删除失败！");
            }else{
                log.info("文件"+delF.getName()+"删除成功！");
            }

        }

    }


    public static void main(final String[] args) throws InterruptedException {
//        long fileSize = getFileSize("d:/gameFile");
//        System.out.println(fileSize);
//        fileMove("D:\\tmp","D:\\tmp1");
        zipFiles("D:/uploadData/123","123");
    }
}
